package com.pi.base.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**
 * 时间工具
 * 
 * @author DJ
 *
 */
public class DateTimeUtil {

	public static final String FORMAT1 = "yyyy-MM-dd HH:mm:ss";
	public static final String FORMAT2 = "yyyy-MM-dd";
	public static final String FORMAT3 = "yyyy-MM-dd HH:mm";
	/**
	 * 以yyyy-MM-dd HH:mm:ss获得当前时间
	 * 
	 * @return
	 */
	public static String getCurrTime() {
		Date d = new Date();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		String dateNowStr = sdf.format(d);
		return dateNowStr;
	}
	
	/**
	 * 以fmt格式获得当前时间
	 * 
	 * @return
	 */
	public static String getCurrTimeFmt(String fmt) {
		Date d = new Date();
		return getTimeFmt(d,fmt);
	}
	
	/**
	 * 以fmt格式获得当前时间
	 * 
	 * @return
	 */
	public static String getTimeFmt(Date d,String fmt) {
		SimpleDateFormat sdf = new SimpleDateFormat(fmt);
		String dateNowStr = sdf.format(d);
		return dateNowStr;
	}

	/**
	 * 从String 获得Date
	 * 
	 * @throws ParseException
	 */
	public static Date getDateByStringFmt(String timeString, String fmt)
			throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat(fmt);
		Date date = sdf.parse(timeString);
		return date;
	}

	/**
	 * 从格式为"yyyy-MM-dd HH:mm:ss" 的String 获得Date
	 * 
	 * @throws ParseException
	 */
	public static Date getDateByString(String timeString) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date = sdf.parse(timeString);
		return date;
	}

	/**
	 * 获得当前时间
	 * @return
	 */
	public static Date getCurrDate() {
		return new Date();
	}
	
	/**
	 * 根据间隔日期查询某天的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getDateBySplitHour(int splitHour) {  
	    Date dNow = new Date();   //当前时间
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dNow);  
        calendar.add(Calendar.HOUR_OF_DAY,splitHour);  
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	/**
	 * 根据间隔日期查询某天的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getDateBySplitDay(int splitDay) {  
	    Date dNow = new Date();   //当前时间
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dNow);  
        calendar.add(Calendar.DATE, splitDay);  
        calendar.set(Calendar.HOUR_OF_DAY,0);  
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	/**
	 * 根据间隔日期查询某天的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getDateBySplitDay(Date date,int splitDay) {  
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.add(Calendar.DATE, splitDay);  
        calendar.set(Calendar.HOUR_OF_DAY,0);  
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	/**
	 * 根据间隔日期查询某天最晚的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getDateBySplitDayLatest(int splitDay) {  
	    Date dNow = new Date();   //当前时间
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dNow);  
        calendar.add(Calendar.DATE, splitDay);  
        calendar.set(Calendar.HOUR_OF_DAY,23);  
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	/**
	 * 根据间隔日期查询某天最晚的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getDateBySplitDayLatest(Date dNow,int splitDay) {  
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dNow);  
        calendar.add(Calendar.DATE, splitDay);  
        calendar.set(Calendar.HOUR_OF_DAY,23);  
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	/**
	 * 设置时间点为00:00:00
	 * @param splitDay
	 * @return
	 */
	public static Date getDateEarly(Date date) {  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.set(Calendar.HOUR_OF_DAY,0);  
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0); 
        return calendar.getTime();  
      } 
	
	/**
	 * 设置时间点为00:00:00
	 * @param splitDay
	 * @return
	 */
	public static Date getDateLatest(Date date) {  
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.set(Calendar.HOUR_OF_DAY,23);  
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59); 
        return calendar.getTime();  
      } 
	
	/**
	 * 根据间隔日期查询某月的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getMonthDateBySplitDay(int splitMonth) {  
	    Date dNow = new Date();   //当前时间
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dNow);  
        calendar.add(Calendar.MONTH, splitMonth);  
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY,0);  
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	
	/**
	 * 根据间隔日期查询某月的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getMonthDateBySplitDay(Date date,int splitMonth) {  
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(date);  
        calendar.add(Calendar.MONTH, splitMonth);  
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	/**
	 * 根据间隔日期查询某月的时间
	 * @param splitDay
	 * @return
	 */
	public static Date getYearDateBySplitDay(int splitYear) {  
	    Date dNow = new Date();   //当前时间
		Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance();  
        calendar.setTime(dNow);  
        calendar.add(Calendar.YEAR, splitYear); 
        calendar.set(Calendar.MONTH, 0);  
        calendar.set(Calendar.DAY_OF_MONTH, 1);
        calendar.set(Calendar.HOUR_OF_DAY,0);  
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        dBefore = calendar.getTime();  
        return dBefore;  
      } 
	
	/**
	 * 取得日期：年
	 * 
	 * @param date
	 * @return
	 */
	public static int getYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int year = c.get(Calendar.YEAR);
		return year;
	}

	/**
	 * 取得日期：月
	 * 
	 * @param date
	 * @return
	 */
	public static int getMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		return month + 1;
	}

	/**
	 * 取得日期：日
	 * 
	 * @param date
	 * @return
	 */
	public static int getDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int da = c.get(Calendar.DAY_OF_MONTH);
		return da;
	}

	/**
	 * 取得当天日期是周几
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekDay(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int week_of_year = c.get(Calendar.DAY_OF_WEEK);
		return week_of_year - 1;
	}

	
	/**
	 * 取得一年的第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDayOfYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, 1);
		c.set(Calendar.MONTH, 0);
        c.set(Calendar.HOUR_OF_DAY,0);  
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
		return c.getTime();
	}
	
	/**
	 * 取得一年的第几周
	 * 
	 * @param date
	 * @return
	 */
	public static int getWeekOfYear(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int week_of_year = c.get(Calendar.WEEK_OF_YEAR);
		return week_of_year;
	}

	/**
	 * 取得月的剩余天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getRemainDayOfMonth(Date date) {
		int dayOfMonth = getDayOfMonth(date);
		int day = getPassDayOfMonth(date);
		return dayOfMonth - day;
	}

	/**
	 * 取得月已经过的天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getPassDayOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.get(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得月天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.getActualMaximum(Calendar.DAY_OF_MONTH);
	}

	/**
	 * 取得月第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH));
        c.set(Calendar.HOUR_OF_DAY,0);  
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
		return c.getTime();
	}

	/**
	 * 取得月最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDateOfMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
		return c.getTime();
	}

	/**
	 * 取得季度第一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getFirstDateOfQuarter(Date date) {
		return getFirstDateOfMonth(getQuarterDate(date)[0]);
	}

	/**
	 * 取得季度最后一天
	 * 
	 * @param date
	 * @return
	 */
	public static Date getLastDateOfQuarter(Date date) {
		return getLastDateOfMonth(getQuarterDate(date)[2]);
	}

	/**
	 * 取得季度天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getDayOfQuarter(Date date) {
		int day = 0;
		Date[] seasonDates = getQuarterDate(date);
		for (Date date2 : seasonDates) {
			day += getDayOfMonth(date2);
		}
		return day;
	}

	/**
	 * 取得季度剩余天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getRemainDayOfQuareter(Date date) {
		return getDayOfQuarter(date) - getPassDayOfQuarter(date);
	}

	/**
	 * 取得季度已过天数
	 * 
	 * @param date
	 * @return
	 */
	public static int getPassDayOfQuarter(Date date) {
		int day = 0;

		Date[] quarterDates = getQuarterDate(date);

		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);

		if (month == Calendar.JANUARY || month == Calendar.APRIL
				|| month == Calendar.JULY || month == Calendar.OCTOBER) {// 季度第一个月
			day = getPassDayOfMonth(quarterDates[0]);
		} else if (month == Calendar.FEBRUARY || month == Calendar.MAY
				|| month == Calendar.AUGUST || month == Calendar.NOVEMBER) {// 季度第二个月
			day = getDayOfMonth(quarterDates[0])
					+ getPassDayOfMonth(quarterDates[1]);
		} else if (month == Calendar.MARCH || month == Calendar.JUNE
				|| month == Calendar.SEPTEMBER || month == Calendar.DECEMBER) {// 季度第三个月
			day = getDayOfMonth(quarterDates[0])
					+ getDayOfMonth(quarterDates[1])
					+ getPassDayOfMonth(quarterDates[2]);
		}
		return day;
	}

	/**
	 * 取得季度月
	 * 
	 * @param date
	 * @return
	 */
	public static Date[] getQuarterDate(Date date) {
		Date[] season = new Date[3];

		Calendar c = Calendar.getInstance();
		c.setTime(date);

		int nQuarter = getQuarter(date);
		if (nQuarter == 1) {// 第一季度
			c.set(Calendar.MONTH, Calendar.JANUARY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.FEBRUARY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MARCH);
			season[2] = c.getTime();
		} else if (nQuarter == 2) {// 第二季度
			c.set(Calendar.MONTH, Calendar.APRIL);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.MAY);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.JUNE);
			season[2] = c.getTime();
		} else if (nQuarter == 3) {// 第三季度
			c.set(Calendar.MONTH, Calendar.JULY);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.AUGUST);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.SEPTEMBER);
			season[2] = c.getTime();
		} else if (nQuarter == 4) {// 第四季度
			c.set(Calendar.MONTH, Calendar.OCTOBER);
			season[0] = c.getTime();
			c.set(Calendar.MONTH, Calendar.NOVEMBER);
			season[1] = c.getTime();
			c.set(Calendar.MONTH, Calendar.DECEMBER);
			season[2] = c.getTime();
		}
		return season;
	}

	/**
	 * 
	 * 1 第一季度 2 第二季度 3 第三季度 4 第四季度
	 * 
	 * @param date
	 * @return
	 */
	public static int getQuarter(Date date) {

		int quarter = 0;

		Calendar c = Calendar.getInstance();
		c.setTime(date);
		int month = c.get(Calendar.MONTH);
		switch (month) {
		case Calendar.JANUARY:
		case Calendar.FEBRUARY:
		case Calendar.MARCH:
			quarter = 1;
			break;
		case Calendar.APRIL:
		case Calendar.MAY:
		case Calendar.JUNE:
			quarter = 2;
			break;
		case Calendar.JULY:
		case Calendar.AUGUST:
		case Calendar.SEPTEMBER:
			quarter = 3;
			break;
		case Calendar.OCTOBER:
		case Calendar.NOVEMBER:
		case Calendar.DECEMBER:
			quarter = 4;
			break;
		default:
			break;
		}
		return quarter;
	}

	/**
	 * 计算时差
	 * 
	 * @param beginDate
	 * @param endDate
	 * @return
	 */
	public static Duration getDuration(Date beginDate, Date endDate) {
		Long beginDateLong = beginDate.getTime(); // Date型转换成Long型毫秒数，用于计算
		Long endDateLong = endDate.getTime();
		Long durationLong = endDateLong - beginDateLong;

		long totalSeconds = durationLong / 1000;// 总共的秒数
		long secondsOfDay = 24 * 60 * 60;// 一天的秒数
		long secondsOfHour = 60 * 60; // 一小时的秒数
		long secondsOfMinute = 60; // 一分钟的秒数

		long days = totalSeconds / secondsOfDay;// 得到天数
		long hours = (totalSeconds % secondsOfDay) / secondsOfHour;// 余数中的小时个数
		long minutes = ((totalSeconds % secondsOfDay) % secondsOfHour)
				/ secondsOfMinute; // 余数中的分钟数
		long seconds = totalSeconds % 60;// 余数中的秒数

		Duration duration = new DateTimeUtil.Duration();
		duration.setDays(days);
		duration.setHours(hours);
		duration.setMinutes(minutes);
		duration.setSeconds(seconds);

		return duration;
	}

	static class Duration {
		private long days;
		private long hours;
		private long minutes;
		private long seconds;

		public long getDays() {
			return days;
		}

		public void setDays(long days) {
			this.days = days;
		}

		public long getHours() {
			return hours;
		}

		public void setHours(long hours) {
			this.hours = hours;
		}

		public long getMinutes() {
			return minutes;
		}

		public void setMinutes(long minutes) {
			this.minutes = minutes;
		}

		public long getSeconds() {
			return seconds;
		}

		public void setSeconds(long seconds) {
			this.seconds = seconds;
		}

		public String format() {
			if (days != 0) {
				return days + "天" + hours + "时" + minutes + "分" + seconds + "秒";
			} else {
				return hours + "时" + minutes + "分" + seconds + "秒";
			}
		}
	}
}
